import { NextRequest, NextResponse } from 'next/server'
import { db } from '@/lib/db'

export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url)
    const projectId = searchParams.get('projectId')
    const iterationId = searchParams.get('iterationId')
    const status = searchParams.get('status')
    const assigneeId = searchParams.get('assigneeId')

    const where: any = {}
    if (projectId) where.projectId = projectId
    if (iterationId) where.iterationId = iterationId
    if (status) where.status = status
    if (assigneeId) where.assigneeId = assigneeId

    const requirements = await db.requirement.findMany({
      where,
      include: {
        project: {
          select: { id: true, name: true, key: true }
        },
        iteration: {
          select: { id: true, name: true }
        },
        creator: {
          select: { id: true, name: true, username: true }
        },
        assignee: {
          select: { id: true, name: true, username: true }
        },
        _count: {
          select: {
            tasks: true,
            bugs: true,
            comments: true
          }
        }
      },
      orderBy: { createdAt: 'desc' }
    })

    return NextResponse.json(requirements)
  } catch (error) {
    console.error('Error fetching requirements:', error)
    return NextResponse.json(
      { error: 'Failed to fetch requirements' },
      { status: 500 }
    )
  }
}

export async function POST(request: NextRequest) {
  try {
    const body = await request.json()
    const {
      projectId,
      iterationId,
      title,
      description,
      type,
      priority,
      status,
      creatorId,
      assigneeId,
      estimate
    } = body

    if (!projectId || !title || !creatorId) {
      return NextResponse.json(
        { error: 'Missing required fields: projectId, title, and creatorId are required' },
        { status: 400 }
      )
    }

    // Validate that project exists
    const project = await db.project.findUnique({
      where: { id: projectId }
    })

    if (!project) {
      return NextResponse.json(
        { error: 'Project not found' },
        { status: 404 }
      )
    }

    // Validate that creator exists
    const creator = await db.user.findUnique({
      where: { id: creatorId }
    })

    if (!creator) {
      return NextResponse.json(
        { error: 'Creator user not found' },
        { status: 404 }
      )
    }

    // Validate iteration if provided
    if (iterationId) {
      const iteration = await db.iteration.findUnique({
        where: { id: iterationId }
      })

      if (!iteration) {
        return NextResponse.json(
          { error: 'Iteration not found' },
          { status: 404 }
        )
      }

      // Validate that iteration belongs to the project
      if (iteration.projectId !== projectId) {
        return NextResponse.json(
          { error: 'Iteration does not belong to the specified project' },
          { status: 400 }
        )
      }
    }

    // Validate assignee if provided
    if (assigneeId) {
      const assignee = await db.user.findUnique({
        where: { id: assigneeId }
      })

      if (!assignee) {
        return NextResponse.json(
          { error: 'Assignee user not found' },
          { status: 404 }
        )
      }
    }

    const requirement = await db.$transaction(async (tx) => {
      // Double-check all references exist within the transaction
      const project = await tx.project.findUnique({
        where: { id: projectId }
      })

      if (!project) {
        throw new Error('Project not found')
      }

      const creator = await tx.user.findUnique({
        where: { id: creatorId }
      })

      if (!creator) {
        throw new Error('Creator user not found')
      }

      if (iterationId) {
        const iteration = await tx.iteration.findUnique({
          where: { id: iterationId }
        })

        if (!iteration) {
          throw new Error('Iteration not found')
        }

        if (iteration.projectId !== projectId) {
          throw new Error('Iteration does not belong to the specified project')
        }
      }

      if (assigneeId) {
        const assignee = await tx.user.findUnique({
          where: { id: assigneeId }
        })

        if (!assignee) {
          throw new Error('Assignee user not found')
        }
      }

      // Create the requirement
      return await tx.requirement.create({
        data: {
          projectId,
          iterationId,
          title,
          description,
          type,
          priority,
          status: status || 'draft',
          creatorId,
          assigneeId,
          estimate
        },
        include: {
          project: {
            select: { id: true, name: true, key: true }
          },
          iteration: {
            select: { id: true, name: true }
          },
          creator: {
            select: { id: true, name: true, username: true }
          },
          assignee: {
            select: { id: true, name: true, username: true }
          }
        }
      })
    })

    return NextResponse.json(requirement, { status: 201 })
  } catch (error) {
    console.error('Error creating requirement:', error)
    
    // Handle specific Prisma errors
    if (error instanceof Error && error.name === 'PrismaClientKnownRequestError') {
      const prismaError = error as any
      if (prismaError.code === 'P2003') {
        return NextResponse.json(
          { error: 'Foreign key constraint violated. Please ensure all referenced entities exist.' },
          { status: 400 }
        )
      }
    }
    
    return NextResponse.json(
      { error: 'Failed to create requirement' },
      { status: 500 }
    )
  }
}